package android.sdk;

 
import java.util.ArrayList;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;

public abstract class SDKClientActivity extends Activity implements OnClickListener, OnLongClickListener, OnTouchListener {

	private Intent intent;
	
	private ArrayList<Integer> onClick; 
	private ArrayList<Integer> onLongClick; 
	private ArrayList<Integer> onTouch; 
	
	private SDKBroadcastReceiver broadcastReceiver;
	public static final String CONNECTION_ESTABLISHED = "android.sdk.CONNECTION_ESTABLISHED";
	public static final String CONNECTION_FAILED = "android.sdk.CONNECTION_FAILED";
	public static final String REGISTER_CLICK_EVENT = "android.sdk.REGISTER_CLICK_EVENT";
	public static final String UNREGISTER_CLICK_EVENT = "android.sdk.UNREGISTER_CLICK_EVENT";
	public static final String REGISTER_LONGCLICK_EVENT = "android.sdk.REGISTER_LONGCLICK_EVENT";
	public static final String UNREGISTER_LONGCLICK_EVENT = "android.sdk.UNREGISTER_LONGCLICK_EVENT";
	public static final String REGISTER_TOUCH_EVENT = "android.sdk.REGISTER_TOUCH_EVENT";
	public static final String UNREGISTER_TOUCH_EVENT = "android.sdk.UNREGISTER_TOUCH_EVENT";
	public static final String UNREGISTER_ALL_EVENTS = "android.sdk.UNREGISTER_ALL_EVENTS";
	
	public static final String VIEW_ID = "android.sdk.VIEW_ID";
	public static final String CONNECTION_FAILED_REASON = "android.sdk.CONNECTION_FAILED_REASON";
	
	public static final String ON_CLICK = "android.sdk.ON_CLICK";
	public static final String ON_LONG_CLICK = "android.sdk.ON_LONG_CLICK";
	public static final String ON_TOUCH = "android.sdk.ON_TOUCH";
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		onClick = new ArrayList<Integer>();
		onLongClick = new ArrayList<Integer>();
		onTouch = new ArrayList<Integer>();
		
		broadcastReceiver = new SDKBroadcastReceiver();
		IntentFilter intentFilter = new IntentFilter();
		intentFilter.addAction(CONNECTION_ESTABLISHED);
		intentFilter.addAction(CONNECTION_FAILED);
		intentFilter.addAction(REGISTER_CLICK_EVENT);
		intentFilter.addAction(UNREGISTER_CLICK_EVENT);
		intentFilter.addAction(REGISTER_LONGCLICK_EVENT);
		intentFilter.addAction(UNREGISTER_LONGCLICK_EVENT);
		intentFilter.addAction(REGISTER_TOUCH_EVENT);
		intentFilter.addAction(UNREGISTER_TOUCH_EVENT);
		intentFilter.addAction(UNREGISTER_ALL_EVENTS);
		registerReceiver(broadcastReceiver, intentFilter);
		
        intent = new Intent(this, SDKClientService.class);
        startService(intent);
	}
	
	protected void connect(String ip, int port) {
		connect(ip, port, 5000);
	}
	
	protected void connect(String ip, int port, int timeout){
        Intent i = this.intent.setAction(SDKClientService.CONNECT);
        i.putExtra(SDKClientService.IP, ip);
        i.putExtra(SDKClientService.PORT, port);
        i.putExtra(SDKClientService.TIMEOUT, timeout);
        startService(i);
	}
    
	protected void disconnect() {
		Intent i = this.intent.setAction(SDKClientService.DISCONNECT);
		startService(i);
	}
	
	protected void registerView(View view, String name) {
		registerView(view.getId(), name);
	}
	
	protected void registerView(int id, String name) {
		Intent i = this.intent.setAction(SDKClientService.REGISTER_VIEW);
		i.putExtra(SDKClientService.ID, id);
		i.putExtra(SDKClientService.NAME, name);
		startService(i);
	}
	
	@Override
    protected void onResume() {
        super.onResume();
         
        Intent i = this.intent.setAction(SDKClientService.ON_RESUME);
        startService(i);
	}

	@Override
    protected void onPause() {
        super.onPause();
        
        Intent i = this.intent.setAction(SDKClientService.ON_PAUSE);
        startService(i);
    }
	
    protected void onDestroy() {
        super.onDestroy();
     
        Log.i("Tesis", "Activity is finishing: " + isFinishing());
        
        unregisterReceiver(broadcastReceiver);
        
        if (isFinishing())
        	stopService(this.intent);
    }
    
    protected void onSaveInstanceState (Bundle outState) {
    	outState.putIntegerArrayList(ON_CLICK, this.onClick);
    	outState.putIntegerArrayList(ON_LONG_CLICK, this.onLongClick);
    	outState.putIntegerArrayList(ON_TOUCH, this.onTouch);
    	super.onSaveInstanceState(outState);
    }
    
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
    	super.onRestoreInstanceState(savedInstanceState);
    	
    	if(savedInstanceState != null) {
    		if(savedInstanceState.containsKey(ON_CLICK))
    			onClick = savedInstanceState.getIntegerArrayList(ON_CLICK);
    		if(savedInstanceState.containsKey(ON_LONG_CLICK))
    			onLongClick = savedInstanceState.getIntegerArrayList(ON_LONG_CLICK);
    		if(savedInstanceState.containsKey(ON_TOUCH))
    			onTouch = savedInstanceState.getIntegerArrayList(ON_TOUCH);
    		
    		for(int id : onClick){
    			View view = this.findViewById(id);
    			if(view != null)
    				view.setOnClickListener(this);
    		}

    		for(int id : onLongClick){
    			View view = this.findViewById(id);
    			if(view != null)
    				view.setOnLongClickListener(this);
    		}
    		
    		for(int id : onTouch){
    			View view = this.findViewById(id);
    			if(view != null)
    				view.setOnTouchListener(this);
    		}
    	}
    }
    
    protected void onConnectionEstablished() {}

    protected void onConnectionFailed(String reason) {}

    private class SDKBroadcastReceiver extends BroadcastReceiver {
    	@Override
		public void onReceive(Context context, Intent intent) {
    		View view = null;
    		if (intent.hasExtra(VIEW_ID))
    			view = findViewById(intent.getIntExtra(VIEW_ID, 0));
    		
			if (intent.getAction().equals(CONNECTION_ESTABLISHED))
				onConnectionEstablished();
			else if (intent.getAction().equals(CONNECTION_FAILED)){
				onConnectionFailed(intent.getStringExtra(CONNECTION_FAILED_REASON));
			}else if (intent.getAction().equals(REGISTER_CLICK_EVENT) && view != null){
				view.setOnClickListener(SDKClientActivity.this);
				onClick.add(view.getId());
	    	}else if (intent.getAction().equals(REGISTER_LONGCLICK_EVENT) && view != null){
				view.setOnLongClickListener(SDKClientActivity.this);
	    		onLongClick.add(view.getId());
	    	}else if (intent.getAction().equals(REGISTER_TOUCH_EVENT) && view != null){
				view.setOnTouchListener(SDKClientActivity.this);
				onTouch.add(view.getId());
			}else if (intent.getAction().equals(UNREGISTER_CLICK_EVENT) && view != null){
				view.setOnClickListener(null);
				onClick.remove(view.getId());
			}else if (intent.getAction().equals(UNREGISTER_LONGCLICK_EVENT) && view != null){
				view.setOnLongClickListener(null);
				onLongClick.remove(view.getId());
			}else if (intent.getAction().equals(UNREGISTER_TOUCH_EVENT) && view != null){
				view.setOnTouchListener(null);
				onTouch.remove(view.getId());
			}else if (intent.getAction().equals(UNREGISTER_ALL_EVENTS)) {
				unregisterAllEvents();
			}
    	}
    }

	@Override
	public boolean onTouch(View view, MotionEvent motionEvent) {
		if(motionEvent.getAction() > 6)
			return false;
		
		Intent i = this.intent.setAction(SDKClientService.TOUCH_EVENT);
		i.putExtra(SDKClientService.ID, view.getId());
		i.putExtra(SDKClientService.MOTION_EVENT, motionEvent);
		startService(i);
		return true;
	}

	@Override
	public boolean onLongClick(View view) {
        Intent i = this.intent.setAction(SDKClientService.LONGCLICK_EVENT);
        i.putExtra(SDKClientService.ID, view.getId());
        startService(i);
		return true;
	}

	@Override
	public void onClick(View view) {
        Intent i = this.intent.setAction(SDKClientService.CLICK_EVENT);
        i.putExtra(SDKClientService.ID, view.getId());
        startService(i);
	}
	
	private void unregisterAllEvents() {
		for(int id : onClick){
			View view = this.findViewById(id);
			if(view != null)
				view.setOnClickListener(null);
		}

		for(int id : onLongClick){
			View view = this.findViewById(id);
			if(view != null)
				view.setOnLongClickListener(null);
		}
		
		for(int id : onTouch){
			View view = this.findViewById(id);
			if(view != null)
				view.setOnTouchListener(null);
		}
		
		onClick = new ArrayList<Integer>();
		onLongClick = new ArrayList<Integer>();
		onTouch = new ArrayList<Integer>();
	}
}
